﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;
using HYCodeBase.WinForm;
using YRevitJig;

namespace HYIndicateDimension.DrawLaneLine
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class AppDrawLaneLines : IExternalApplication
	{
		public Result OnStartup(UIControlledApplication application)
		{
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public Result OnShutdown(UIControlledApplication application)
		{
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public static void DrawLines(UIApplication app, WindowHandle _hWndRevit)
		{
			AppDrawLaneLines.m_app = app;
			UIDocument activeUIDocument = app.ActiveUIDocument;
			Document document = activeUIDocument.Document;
			Selection selection = activeUIDocument.Selection;
			AppDrawLaneLines.m_hWndRevit = _hWndRevit;
			List<string> graphicsStyleList = AppDrawLaneLines.GetGraphicsStyleList();
			if (graphicsStyleList.Count < 1)
			{
				TaskDialog.Show("提示", "没有提取到线样式！");
				return;
			}
			DrawZoneForm drawZoneForm = new DrawZoneForm(AppDrawLaneLines.m_hWndRevit, graphicsStyleList);
			drawZoneForm.Show(AppDrawLaneLines.m_hWndRevit);
			int wMsg = 7;
			AppDrawLaneLines.SendMessage(AppDrawLaneLines.m_hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			ViewAssist.ViewValidating(activeUIDocument.Document, activeUIDocument.ActiveView);
			XYZ xyz = XYZ.Zero;
			bool flag = true;
			XLineJig xlineJig = new XLineJig(activeUIDocument);
			XArc3PtJig xarc3PtJig = new XArc3PtJig(activeUIDocument);
			XArcJig xarcJig = new XArcJig(activeUIDocument);
			TransactionGroup transactionGroup = new TransactionGroup(document, "TransactionGroup");
			transactionGroup.Start();
			for (;;)
			{
				try
				{
					if (drawZoneForm.m_eDrawMode == DrawMode.Line)
					{
						if (flag)
						{
							xlineJig.StartPoint = null;
							xyz = xlineJig.PickStartPoint("请确定直线起点：");
							if (xyz == null)
							{
								if (!AppDrawLaneLines.isCommandOver(drawZoneForm))
								{
									continue;
								}
								break;
							}
						}
						xlineJig.EndPoint = null;
						XYZ xyz2 = xlineJig.PickEndPoint(xyz, "请确定直线终点：");
						if (xyz2 == null)
						{
							if (!AppDrawLaneLines.isCommandOver(drawZoneForm))
							{
								continue;
							}
							break;
						}
						else
						{
							try
							{
								Line curve = Line.CreateBound(xyz, xyz2);
								AppDrawLaneLines.CreateDetailCurve(document, curve, drawZoneForm);
								xyz = xyz2;
								flag = !drawZoneForm.Chain;
								continue;
							}
							catch (Exception)
							{
								continue;
							}
						}
					}
					if (DrawMode.Arc3Pt == drawZoneForm.m_eDrawMode)
					{
						if (flag)
						{
							xarc3PtJig.StartPoint = null;
							xyz = xarc3PtJig.PickStartPoint("请确定圆弧起点：");
							if (xyz == null)
							{
								if (!AppDrawLaneLines.isCommandOver(drawZoneForm))
								{
									continue;
								}
								break;
							}
						}
						xarc3PtJig.EndPoint = null;
						XYZ xyz3 = xarc3PtJig.PickEndPoint(xyz, "请确定圆弧终点：");
						if (xyz3 == null)
						{
							if (!AppDrawLaneLines.isCommandOver(drawZoneForm))
							{
								continue;
							}
							break;
						}
						else
						{
							xarc3PtJig.OnCurvePoint = null;
							XYZ xyz4 = xarc3PtJig.PickOnCurvePoint(xyz, xyz3, "请确定圆弧上的点：");
							if (xyz4 == null)
							{
								if (!AppDrawLaneLines.isCommandOver(drawZoneForm))
								{
									continue;
								}
								break;
							}
							else
							{
								try
								{
									Arc curve2 = document.CreatYJKArc(xyz, xyz3, xyz4);
									AppDrawLaneLines.CreateDetailCurve(document, curve2, drawZoneForm);
									xyz = xyz3;
									flag = !drawZoneForm.Chain;
									continue;
								}
								catch
								{
									continue;
								}
							}
						}
					}
					if (DrawMode.ArcCenter == drawZoneForm.m_eDrawMode)
					{
						xarcJig.CenterPoint = null;
						xyz = xarcJig.PickCenterPoint("请确定圆弧中心点：");
						if (xyz == null)
						{
							if (AppDrawLaneLines.isCommandOver(drawZoneForm))
							{
								break;
							}
						}
						else
						{
							xarcJig.StartPoint = null;
							XYZ xyz5 = xarcJig.PickStartPoint(xyz, "请确定圆弧起点：");
							if (xyz5 == null)
							{
								if (AppDrawLaneLines.isCommandOver(drawZoneForm))
								{
									break;
								}
							}
							else
							{
								xarcJig.EndPoint = null;
								XYZ xyz6 = xarcJig.PickEndPoint(xyz, xyz5, "请确定圆弧终点：");
								if (xyz6 == null)
								{
									if (AppDrawLaneLines.isCommandOver(drawZoneForm))
									{
										break;
									}
								}
								else
								{
									Arc curve3 = AppDrawLaneLines.CreateArc(document, xyz, xyz5, xyz6);
									AppDrawLaneLines.CreateDetailCurve(document, curve3, drawZoneForm);
									flag = true;
								}
							}
						}
					}
					else if (DrawMode.Delete == drawZoneForm.m_eDrawMode)
					{
						DetailCurveFilter detailCurveFilter = new DetailCurveFilter();
						IEnumerable<Element> enumerable = selection.PickElementsByRectangle(detailCurveFilter, "请框选需要删除的车道线");
						Transaction transaction = new Transaction(document, "DeleteElements");
						transaction.Start();
						foreach (Element element in enumerable)
						{
							document.Delete(element.Id);
						}
						transaction.Commit();
						flag = true;
					}
					else if (DrawMode.Finish == drawZoneForm.m_eDrawMode)
					{
						break;
					}
					continue;
				}
				catch (Autodesk.Revit.Exceptions.OperationCanceledException)
				{
					if (drawZoneForm.m_clickMode)
					{
						drawZoneForm.m_clickMode = false;
						continue;
					}
					transactionGroup.Commit();
					drawZoneForm.Close();
					return;
				}
				catch (Exception ex)
				{
					YJKMessageBox.Show(ex.Message);
					continue;
				}
				break;
			}
			transactionGroup.Commit();
			drawZoneForm.Close();
			xlineJig.Dispose();
		}

		private static List<string> GetGraphicsStyleList()
		{
			List<string> list = new List<string>();
			foreach (Element element in new FilteredElementCollector(AppDrawLaneLines.m_app.ActiveUIDocument.Document).OfClass(typeof(GraphicsStyle)))
			{
				GraphicsStyle graphicsStyle = element as GraphicsStyle;
				if (graphicsStyle != null)
				{
					Category graphicsStyleCategory = graphicsStyle.GraphicsStyleCategory;
					if (graphicsStyleCategory != null)
					{
						Category parent = graphicsStyleCategory.Parent;
						if (parent != null && (parent.Name.CompareTo("线") == 0 || parent.Name.CompareTo("Lines") == 0) && graphicsStyleCategory.Name.CompareTo(graphicsStyle.Name) == 0)
						{
							BuiltInCategory integerValue = graphicsStyleCategory.Id.IntegerValue;
							if (integerValue != -2000066 && integerValue != -2000077 && integerValue != -2000045 && integerValue != -2000284 && integerValue != -2000079 && integerValue != -2000831 && integerValue != -2009018 && integerValue != -2000953 && integerValue != -2009019 && integerValue != -2000954 && !list.Contains(graphicsStyleCategory.Name))
							{
								list.Add(graphicsStyleCategory.Name);
							}
						}
					}
				}
			}
			return list;
		}

		private static bool isCommandOver(DrawZoneForm dlgDraw)
		{
			if (dlgDraw.m_clickMode)
			{
				dlgDraw.m_clickMode = false;
				return false;
			}
			return true;
		}

		private static DetailCurve CreateDetailCurve(Autodesk.Revit.DB.Document doc, Curve curve, DrawZoneForm dlgDraw)
		{
			AppDrawLaneLines.m_LineStyle = dlgDraw.LineStyle;
			if (!AppDrawLaneLines.GetGraphicsStyle(doc, AppDrawLaneLines.m_LineStyle, out AppDrawLaneLines.m_curveStyle))
			{
				return null;
			}
			DetailCurve detailCurve = null;
			Transaction transaction = new Transaction(doc, "DrawCurve");
			try
			{
				transaction.Start();
				detailCurve = doc.CreatYJKDetailCurve(curve);
				detailCurve.LineStyle = AppDrawLaneLines.m_curveStyle;
				LaneLineXDataManager.WriteXData(detailCurve, "车道线");
				transaction.Commit();
			}
			catch (Exception ex)
			{
				transaction.RollBack();
				YJKMessageBox.Show(ex.Message);
			}
			return detailCurve;
		}

		public static int RgbColorToInt(System.Drawing.Color colorRgb)
		{
			return (int)colorRgb.B << 16 | (int)((ushort)((int)colorRgb.G << 8 | (int)colorRgb.R));
		}

		public static System.Drawing.Color IntToRgbColor(int colorInt)
		{
			int red = colorInt & 255;
			int green = colorInt >> 8 & 255;
			int blue = colorInt >> 16 & 255;
			return System.Drawing.Color.FromArgb(red, green, blue);
		}

		private static bool GetGraphicsStyle(Autodesk.Revit.DB.Document doc, string linestylename, out GraphicsStyle lineStyle)
		{
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(GraphicsStyle)))
			{
				GraphicsStyle graphicsStyle = element as GraphicsStyle;
				if (graphicsStyle != null && graphicsStyle.Name.CompareTo(linestylename) == 0)
				{
					lineStyle = graphicsStyle;
					return true;
				}
			}
			lineStyle = null;
			return false;
		}

		public static Arc CreateArc(Autodesk.Revit.DB.Document document, XYZ ptCenter, XYZ ptArcStart, XYZ ptArcEnd)
		{
			double length = (ptArcStart - ptCenter).GetLength();
			XYZ xyz = ptArcStart - ptCenter;
			XYZ xyz2 = ptArcEnd - ptCenter;
			xyz.AngleOnPlaneTo(xyz2, XYZ.BasisZ);
			double num;
			double num2;
			if (xyz.AngleOnPlaneTo(xyz2, XYZ.BasisZ) <= Math.PI)
			{
				num = XYZ.BasisX.AngleOnPlaneTo(xyz, XYZ.BasisZ);
				num2 = XYZ.BasisX.AngleOnPlaneTo(xyz2, XYZ.BasisZ);
				if (num > num2)
				{
					num2 += Math.PI*2;
				}
				return document.CreatYJKArc(ptCenter, length, num, num2, XYZ.BasisX, XYZ.BasisY);
			}
			num = XYZ.BasisX.Negate().AngleOnPlaneTo(xyz, XYZ.BasisZ.Negate());
			num2 = XYZ.BasisX.Negate().AngleOnPlaneTo(xyz2, XYZ.BasisZ.Negate());
			if (num > num2)
			{
				num2 += Math.PI*2;
			}
			return document.CreatYJKArc(ptCenter, length, num, num2, XYZ.BasisX.Negate(), XYZ.BasisY);
		}

		private static WindowHandle m_hWndRevit;

		private static UIApplication m_app;

		private static string m_LineStyle;

		private static GraphicsStyle m_curveStyle;
	}
}
